///implementation of groovey particle class
#include "gparticle.hpp"

GParticle::GParticle(const int Life, 
					const int Size,
					const boost::numeric::ublas::vector<float>& Loc, 
					const boost::numeric::ublas::vector<float>& Vel, 
					const boost::numeric::ublas::vector<float>& Acc):
					loc(boost::numeric::ublas::vector<float> (2)),
					vel(boost::numeric::ublas::vector<float> (2)),
					acc(boost::numeric::ublas::vector<float> (2))
{
    life = Life;
    size = Size;
    loc = Loc;
    vel = Vel;
    acc = Acc;
}///////////////////////////////Particle Constructor - default

GParticle::GParticle():loc(boost::numeric::ublas::vector<float> (2)),
					vel(boost::numeric::ublas::vector<float> (2)),
					acc(boost::numeric::ublas::vector<float> (2))
{
    life = 0;
    size = 0;
}///////////////////////////////Particle Constructor - risky

int GParticle::Die(const int Damage)
{
    life -= Damage;
    return life;
}///////////////////////////////Die()

bool GParticle::Dead()
{
    return life <= 0;
}///////////////////////////////Dead()

void GParticle::setLives(const int Lives)
{
    life = Lives;
}///////////////////////////////setLives()

bool GParticle::Update(const int limit_X, 
						const int limit_Y)
{
    ///NOTE! We should consider adding damping updates to the acceleration so that the acceleration slows too.
    //////this would be like having a world where there's wind resistance or otherwise.
    vel[0] += acc[0];
    vel[1] += acc[1];
    loc[0] += vel[0];
    loc[1] += vel[1];
    
    ///NOTE! We need to reset acceleration now that we are done calculating the update.
    ////otherwise who knows where the forces will lead us?!?!
    acc[0] = 0;
    acc[1] = 0;
    
    if ((loc[0] > limit_X) || (loc[0] < 0) || (loc[1] < 0) || (loc[1] > limit_Y)){
        ////if we hit the limits... for now the boundaries of our window
        if( (loc[0] < 0) || (loc[0] > limit_X)){
            ////if we hit the left or right boundaries....
        	vel[0] *= -1; ////deflect off the left or right wall
        }
        else{
            ////otherwise we know by deduction we hit the top or bottom walls
            vel[1] *= -1;////deflect
        }
        
    	return true; ////assumption here is that we didn't hit the corner perfectly, as that would be collision with two walls.
    }
    return false;
}///////////////////////////////Update()

void GParticle::Accelerate(const boost::numeric::ublas::vector<float> Jerk)
{
    acc += Jerk;////What a jerk! Hahahah... I can't get enough of this corny humor
}///////////////////////////////Accelerate()

int GParticle::getLife() const
{
    return life;
}///////////////////////////////Get a life, dude

int GParticle::getSize() const
{
    return size;
}///////////////////////////////getSize()

boost::numeric::ublas::vector<float> GParticle::getLoc() const
{
    return loc;
}///////////////////////////////getLoc()

boost::numeric::ublas::vector<float> GParticle::getVel() const
{
    return vel;
}///////////////////////////////getVel()

boost::numeric::ublas::vector<float> GParticle::getAcc() const
{
    return acc;
}///////////////////////////////getAcc()

void GParticle::setSize(const int Size)
{
}//////////////////////////////setSize()

void GParticle::setLoc(boost::numeric::ublas::vector<float>& Loc)
{
    loc[0] = Loc[0];
    loc[1] = Loc[1];
}///////////////////////////////setLoc()

void GParticle::setVel(boost::numeric::ublas::vector<float> Vel)
{
    vel = Vel;
}///////////////////////////////setVel()

void GParticle::setAcc(boost::numeric::ublas::vector<float> Acc)
{
    acc = Acc;
}///////////////////////////////setAcc()

boost::numeric::ublas::vector<float>& GParticle::Loc()
{
    return loc;
}///////////////////////////////vector& Loc()

boost::numeric::ublas::vector<float>& GParticle::Vel()
{
    return vel;
}///////////////////////////////vector& Vel()

boost::numeric::ublas::vector<float>& GParticle::Acc()
{
    return acc;
}///////////////////////////////vector& Acc()

void GParticle::operator=(const GParticle& GPart)
{
    life = GPart.getLife();
    size = GPart.getSize();
}///////////////////////////////Overloaded assignment operator

